package com.imoblife.brainwavestus.oldMedia;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.ref.WeakReference;
import java.security.SecureRandom;
import java.util.Timer;
import java.util.TimerTask;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.logging.Log;

import com.imoblife.brainwavestus.R;
import com.imoblife.brainwavestus.util.DebugUtil;

import android.R.bool;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.RemoteViews;

public class MediaPlayerService extends Service {

	static String rootPath = "/sdcard/.brainwaves-tus/";
	static final String TAG = "MusicMediaPlayer";
	private static int offset = 100;

	static class BackgoundMediaPlayerIn extends BackgoundMediaPlayer.Stub {

		WeakReference<MediaPlayerService> mService;

		public BackgoundMediaPlayerIn(MediaPlayerService mediaPlayerService) {
			mService = new WeakReference<MediaPlayerService>(mediaPlayerService);

		}

		public boolean play(String inplayFile) throws RemoteException {
			return mService.get().play(inplayFile);

		}

		public void stop() throws RemoteException {

			System.out.println("stop() throws RemoteException");

			mService.get().stop();
		}

		public void start() throws RemoteException {
			mService.get().start();
		}

		public void pause() throws RemoteException {
			mService.get().pause();

		}

		public boolean isPlaying() throws RemoteException {
			return mService.get().isPlaying();
		}

		public long duration() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().duration();
		}

		public long position() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().position();
		}

		public long seek(long whereto) throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().seek(whereto);
		}

		public void setVolume(float vol) throws RemoteException {
			mService.get().setVolume(vol);
		}

		public void setRunningTime(long runningtime) throws RemoteException {
			mService.get().setRunningTime(runningtime);
		}

		public long getRunningTime() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().getRunningTime();
		}

	}

	public void start() {
		mPlayer.start();
		sendNotification();
	}

	public void pause() {
		mPlayer.pause();
		stopForeground(true);
	}

	public long duration() {
		return mPlayer.duration();
	}

	public long position() {

		return mPlayer.position();
	}

	public long seek(long whereto) {
		return mPlayer.seek(whereto);
	}

	public void setVolume(float vol) {
		mPlayer.setVolume(vol);
	}

	private MultiPlayer mPlayer;

	private String mPlayPath;

	private String getPath(String fileName) {
		String subPath = fileName.substring(fileName.indexOf(".") + 1) + "/";
		mPlayPath = rootPath + subPath + fileName;
		return mPlayPath;

	}

	class MultiPlayer {
		private MediaPlayer mMediaPlayer = new MediaPlayer();
		private boolean mIsInitialized = false;
		private boolean mIsPlaying = false;
		private long mCurrentPosition = 0;

		public void reset() {
			mMediaPlayer.reset();
			mIsInitialized = false;
			mIsPlaying = false;
			mCurrentPosition = 0;

		}

		public MultiPlayer() {
			mMediaPlayer.setWakeMode(MediaPlayerService.this,
					PowerManager.PARTIAL_WAKE_LOCK);
		}

		public boolean setDataSourceAsync(String path) {
			mIsPlaying = false;
			try {
				mMediaPlayer.reset();
				RandomAccessFile accessFile = new RandomAccessFile(path, "rwd");
				mMediaPlayer.setDataSource(accessFile.getFD(), 100,
						accessFile.length() - 108);
				mMediaPlayer.prepare();

			} catch (IOException ex) {
				// TODO: notify the user why the file couldn't be opened
				mIsInitialized = false;
				return mIsInitialized;
			} catch (IllegalArgumentException ex) {
				// TODO: notify the user why the file couldn't be opened
				mIsInitialized = false;
				return mIsInitialized;
			}
			mIsInitialized = true;
			return mIsInitialized;
		}

		public boolean isInitialized() {
			return mIsInitialized;
		}

		public boolean start() {

			if (mStartHandler.hasMessages(0)) {
				mStartHandler.removeMessages(0);
			}

			if (!decryptAudioFile(mPlayPath)) {
				return false;
			} else {
				if (setDataSourceAsync(mPlayPath)) {
					mStartHandler.sendEmptyMessageDelayed(0, 10);
					return true;
				}
				return false;
			}

		}

		public Handler mStartHandler = new Handler() {
			public void handleMessage(Message msg) {
				mMediaPlayer.start();
				mMediaPlayer.setLooping(true);
				seek(mCurrentPosition);
				DebugUtil.debug(TAG, "����� mCurrentPosition=" + mCurrentPosition);
				mIsPlaying = true;

			}
		};

		public void stop() {
			mStartHandler.removeCallbacksAndMessages(null);
			mMediaPlayer.reset();
			encryptAudioFile(mPlayPath);
			mIsInitialized = false;
			mIsPlaying = false;
			mCurrentPosition = 0;
			stopForeground(true);
		}

		public boolean isPlaying() {

			return mIsPlaying;
		}

		public void release() {
			mMediaPlayer.release();
		}

		public void pause() {
			mCurrentPosition = position();
			DebugUtil.debug(TAG, "pause  mCurrentPosition=" + mCurrentPosition);
			mStartHandler.removeCallbacksAndMessages(null);
			mMediaPlayer.reset();
			encryptAudioFile(mPlayPath);
			mIsInitialized = false;
			mIsPlaying = false;

		}

		public long duration() {
			return mMediaPlayer.getDuration();
		}

		public long position() {
			return mMediaPlayer.getCurrentPosition();
		}

		public long seek(long whereto) {
			mMediaPlayer.seekTo((int) whereto);
			return whereto;
		}

		public void setVolume(float vol) {
			mMediaPlayer.setVolume(vol, vol);
		}

	}

	BackgoundMediaPlayerIn mBackgoundMediaPlayer = new BackgoundMediaPlayerIn(
			this);

	public IBinder onBind(Intent intent) {
		return mBackgoundMediaPlayer;
	}

	public void onCreate() {
		super.onCreate();
		mPlayer = new MultiPlayer();
		registPhoneState();
		mRunningTime = -1L;
		DebugUtil.debug(TAG, "�������������onCreate");
	}

	private void registPhoneState() {
		TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
	}

	private void unregistPhoneState() {
		TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
	}

	public boolean play(String inplayPath) {

		getPath(inplayPath);
		sendNotification();
		mPlayer.reset();
		return mPlayer.start();

	}

	private void sendNotification() {

		String playname = getSharedPreferences("playNametitle", -1).getString(
				"playNametitle", "");
		Notification notification = new Notification(
				R.drawable.service_notification_icon, playname,
				System.currentTimeMillis());

		notification.setLatestEventInfo(this, playname, getResources()
				.getString(R.string.service_notification_content),
				PendingIntent.getActivity(this, 0, new Intent(
						"android.action.initialize"), 0));
		notification.flags |= Notification.FLAG_ONGOING_EVENT;
		startForeground(0xff, notification);
		DebugUtil.debug(TAG, "sendNotification=" + "��֪ͨ" + playname);

	}

	public void stop() {
		mPlayer.stop();

	}

	public boolean isPlaying() {
		return mPlayer.isPlaying();
	}

	/**
	 * ������Ƶ�ļ����
	 * 
	 * @param audioFileName
	 * @return ���ܳɹ�����true ��֮ false
	 */
	private boolean decryptAudioFile(String path) {

		try {
			// 1 ������Ҫ���ܵ��ļ�
			RandomAccessFile randomAccessFile = new RandomAccessFile(path,
					"rwd");

			// 2 ��ȡ�����ֶ�
			byte[] bs = new byte[112];
			randomAccessFile.seek(offset);
			randomAccessFile.read(bs, 0, 104);
			randomAccessFile.seek(randomAccessFile.length() - 8);
			randomAccessFile.read(bs, 104, 8);

			boolean isDecrypted = true;

			for (int i = 1; i < 9; i++) {
				System.out.println(bs[bs.length - i]);
				if (bs[bs.length - i] != -1) {
					isDecrypted = false;
				}

			}

			if (isDecrypted) {
				System.out.println("�ϴ��Ѿ�����");
				randomAccessFile.close();
				return true;
			}

			// 3 ��ȡ��Կ
			Cipher c1 = getCipher(Cipher.DECRYPT_MODE);

			// 4 ִ�н���
			byte[] cipherByte = c1.doFinal(bs);

			// 5�ظ��ļ�
			// randomAccessFile.setLength(randomAccessFile.length() - 8);
			randomAccessFile.seek(offset);
			randomAccessFile.write(cipherByte);
			randomAccessFile.seek(randomAccessFile.length() - 8);
			randomAccessFile
					.write(new byte[] { -1, -1, -1, -1, -1, -1, -1, -1 });
			// 6���ܳɹ�
			randomAccessFile.close();
			System.out.println("// 6���ܳɹ�");
			return true;

		} catch (FileNotFoundException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {

			e.printStackTrace();
		} catch (BadPaddingException e) {

			e.printStackTrace();
		}
		System.out.println("// 6����ʧ��");
		return false;
	}

	/**
	 * ��ȡ��Կ
	 * 
	 * @param mode
	 *            ���ܻ����
	 * @param context
	 * @return
	 */
	private Cipher getCipher(int mode) {

		SecureRandom sr = new SecureRandom();
		// ����Կ�ļ��л�ȡԭʼ��Կ���
		byte[] rawKeyData = null;

		InputStream fileInputStream;
		try {
			fileInputStream = getAssets().open("icon.apk");
			rawKeyData = new byte[fileInputStream.available()];
			System.out.println(rawKeyData.length);
			fileInputStream.read(rawKeyData);
			fileInputStream.close();

			for (int i = 0; i < rawKeyData.length - 1; i += 2) {
				byte tmp = rawKeyData[i + 1];
				rawKeyData[i + 1] = rawKeyData[i];
				rawKeyData[i] = tmp;
			}

			// ����һ��DESKeySpec����
			DESKeySpec dks = new DESKeySpec(rawKeyData);
			// ����һ����Կ������Ȼ�������DESKeySpec����ת����Secret Key����
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			SecretKey key = keyFactory.generateSecret(dks);
			// Cipher����ʵ����ɽ��ܲ���
			Cipher cipher = Cipher.getInstance("DES");
			cipher.init(mode, key, sr);
			return cipher;
		} catch (Exception e) {

			e.printStackTrace();
		}
		return null;
	}

	/**
	 * ������Ƶ�ļ����
	 * 
	 * @param audioFileName
	 * @return ���ܳɹ�����true ��֮ false
	 */

	private boolean encryptAudioFile(String path) {

		try {
			// 1 ���������ļ�
			RandomAccessFile randomAccessFile = new RandomAccessFile(path,
					"rwd");

			// 2 �����Կ
			Cipher c1 = getCipher(Cipher.ENCRYPT_MODE);

			// 3 ��ȡ�������
			byte[] bs = new byte[104];
			randomAccessFile.seek(offset);
			randomAccessFile.read(bs);

			// 4 ִ�м���
			byte[] cipherByte = c1.doFinal(bs);

			// 5����������
			randomAccessFile.seek(offset);
			randomAccessFile.write(cipherByte, 0, 104);
			randomAccessFile.seek(randomAccessFile.length() - 8);
			randomAccessFile.write(cipherByte, 104, 8);

			// 6���ܳɹ�
			randomAccessFile.close();
			DebugUtil.debug(TAG, "���ܳɹ�");
			return true;

		} catch (FileNotFoundException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {

			e.printStackTrace();
		} catch (BadPaddingException e) {

			e.printStackTrace();
		}
		DebugUtil.debug(TAG, "����ʧ��");
		return false;
	}

	Long mRunningTime = -1L;

	Timer mTimer;

	static Handler mHandler;

	public void setRunningTime(long runningtime) {

		DebugUtil.debug(TAG, "setRunningTime=" + runningtime);

		mRunningTime = runningtime;
		if (mTimer != null) {
			mTimer.cancel();
			mTimer = null;
		}

		if (runningtime == -1) {
			return;
		}

		mTimer = new Timer();

		mTimer.schedule(new TimerTask() {

			public void run() {

				if (!isPlaying()) {
					return;
				}

				mRunningTime -= 1000;

				if (mHandler != null) {
					Message message = mHandler.obtainMessage();
					message.what = 0;
					message.obj = mRunningTime;
					mHandler.sendMessage(message);
				}
				if (mRunningTime <= 0) {

					if (mPlayer.isPlaying()) {
						mPlayer.stop();
					}
					Message message = mHandler.obtainMessage();
					message.what = -1;

					if (mTimer != null) {
						mTimer.cancel();
					}

					mTimer = null;
					mHandler.sendMessage(message);
				}
			}
		}, 1, 1000);

	}

	PhoneStateListener mPhoneStateListener = new PhoneStateListener() {

		boolean mIsPlaying = false;

		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE:
				if (mIsPlaying) {
					mPlayer.start();
					Message message = mHandler.obtainMessage();
					message.what = 1;
					mHandler.sendMessage(message);
				}

				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:
				System.out.println("����");
				break;

			case TelephonyManager.CALL_STATE_RINGING:

				mIsPlaying = mPlayer.isPlaying();
				if (mIsPlaying) {
					mPlayer.pause();
					Message message = mHandler.obtainMessage();
					message.what = -2;
					mHandler.sendMessage(message);
				}
				break;
			}
		}

	};

	public long getRunningTime() {

		return mRunningTime;

	}

	protected static void setMassageHandler(Handler handler) {
		mHandler = handler;
	}

	public void onDestroy() {

		DebugUtil.debug(TAG, "onDestroy ���������");

		if (mTimer != null) {
			mTimer.cancel();
			mTimer = null;
		}

		if (mPlayer != null) {
			mPlayer.release();
			mPlayer = null;
		}
		SharedPreferences preferences = getSharedPreferences("SetTimer", 0);
		preferences.edit().putLong("runningTime", mRunningTime).commit();
		unregistPhoneState();
		super.onDestroy();
	}

}
